package com.liuym.login.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.liuym.common.constants.GradeResponse;
import com.liuym.common.constants.RedisConstants;
import com.liuym.common.constants.ResponseCodeConstants;
import com.liuym.common.dubbo.admin.api.AdminDubboService;
import com.liuym.common.dubbo.admin.dto.AdminDTO;
import com.liuym.common.dubbo.student.api.StudentDubboService;
import com.liuym.common.dubbo.student.dto.StudentDTO;
import com.liuym.common.exception.AdminException;
import com.liuym.common.exception.LoginException;
import com.liuym.common.exception.StudentException;
import com.liuym.common.redis.RedisTemplateManager;
import com.liuym.login.common.LogAndExceptionCommon;
import com.liuym.login.repository.model.bo.LoginUserBO;
import com.liuym.login.service.LoginService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @author LiuYiMing
 * @date 2018/9/18 11:43
 * @describe：
 */
@Service
public class LoginServiceImpl implements LoginService {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference(version = "${student.dubbo.version}")
    private StudentDubboService studentDubboService;

    @Reference(version = "${admin.dubbo.version}")
    private AdminDubboService adminDubboService;
    private static Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);


    @Override
    public String login(LoginUserBO loginUserBO, String role) throws LoginException {
        JSONObject jsonObject = null;
        // jsonObject = JSONObject.parseObject(JSONObject.toJSON(baseParamCheck(studentBO)).toString());
        if ("student".equals(role)) {
            baseParamCheck(loginUserBO);
            StudentDTO student = null;
            try {
                student = studentDubboService.getStudentByNumber(Long.parseLong(loginUserBO.getUserName()));
            } catch (Exception e) {
                if (e instanceof StudentException) {
                    throw LoginException.internalServerError();
                } else {
                    logger.error("error", e);
                    return "账号不存在！";
                }
            }
            if (student != null) {
                if (loginUserBO.getPassword().equals(student.getPassword())) {
                    RedisTemplateManager redisTemplateManager = new RedisTemplateManager(redisTemplate);
                    //与数据库认证成功，生成登陆令牌，缓存登录信息
                    Integer id = student.getId();
                    String token = generateToken(id);//生成登录令牌
                    //开始缓存登陆信息
                    jsonObject = JSONObject.parseObject(JSONObject.toJSON(student).toString());
                    redisTemplateManager.setKey(RedisConstants.STUDENT_LOGIN_USER_PREFIX + token, jsonObject.toJSONString(), RedisConstants.TOKEN_EXPIRE_TIME);
                    return token;
                } else {
                    return "用户名密码错误！";
                }
            } else {
                return "账号不存在！";
            }
        }
        if ("admin".equals(role)) {
            AdminDTO admin = null;
            try {
                admin = adminDubboService.getAdminByUserName(loginUserBO.getUserName());
            } catch (AdminException e) {
                throw LoginException.internalServerError();
            }
            if (admin != null) {
                if (loginUserBO.getPassword().equals(admin.getPassword())) {
                    if (admin.getStatus() == 0) {
                        return ResponseCodeConstants.USERNAME_IS_LOCK_MSG;
                    }
                    RedisTemplateManager redisTemplateManager = new RedisTemplateManager(redisTemplate);
                    //与数据库认证成功，生成登陆令牌，缓存登录信息
                    Integer id = admin.getId();
                    String token = generateToken(id);//生成登录令牌
                    // 开始缓存登陆信息

                    jsonObject = JSONObject.parseObject(JSONObject.toJSON(admin).toString());
                    redisTemplateManager.setKey(RedisConstants.ADMIN_LOGIN_USER_PREFIX + token, jsonObject.toJSONString(), RedisConstants.TOKEN_EXPIRE_TIME);
                    return token;
                } else {
                    return ResponseCodeConstants.USERNAME_OR_PASSWORD_ERROR_MSG;
                }
            } else {
                return "账号不存在！";
            }
        }
        GradeResponse<Object> fail =
                GradeResponse.fail(
                        ResponseCodeConstants.USERNAME_IS_NOT_EXIST_CODE,
                        ResponseCodeConstants.USERNAME_IS_NOT_EXIST_MSG);
        jsonObject = JSONObject.parseObject(JSONObject.toJSON(fail).toString());
        return ResponseCodeConstants.USERNAME_IS_NOT_EXIST_MSG;

        //return jsonObject;
    }

    /**
     * 检查参数是否为空
     *
     * @param loginUserBO
     * @return
     * @throws StudentException
     */
    public void baseParamCheck(LoginUserBO loginUserBO) throws LoginException {

            if (null == loginUserBO.getUserName()) {
                LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                        ResponseCodeConstants.USERNAME_IS_NOT_NULL_CODE,
                        ResponseCodeConstants.USERNAME_IS_NOT_NULL_MSG,
                        "");
            }

        if (null == loginUserBO.getPassword()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.PASSWORD_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.PASSWORD_IS_NOT_NULL_MSG,
                    "");
        }
    }

    /**
     * 生成登录令牌
     *
     * @param userId 用户id
     * @return java.lang.String
     */
    private String generateToken(Integer userId) {
        StringBuilder sb = new StringBuilder();
        sb.append("userId=");
        sb.append(userId);
        sb.append("&timestamp=");
        sb.append(System.currentTimeMillis());
        sb.append("&randomStr=");
        sb.append(RandomStringUtils.randomAlphanumeric(32));
        return DigestUtils.md5Hex(sb.toString());
    }


}
